const { LRUCache } = require('lru-cache');
 
// 创建一个LRU缓存实例，用于存储客户端请求记录
const cache = new LRUCache({
  max: 1000, // 最大缓存数量
  ttl: 60 * 1000, // 缓存过期时间，这里设置为1分钟
});
 
module.exports = (options, app) => {
  // 默认配置
  const defaultOptions = {
    max: 100, // 单位时间内最大请求数
    windowMs: 60 * 1000, // 时间窗口，默认1分钟
  };
  const opts = { ...defaultOptions, ...options };
 
  return async function ratelimit(ctx, next) {
    // 获取客户端IP
    const clientIP = ctx.ip;
    // 生成缓存键
    const key = `ratelimit:${clientIP}`;
 
    // 获取当前IP的请求记录
    let record = cache.get(key);
    if (!record) {
      record = { count: 0, startTime: Date.now() };
    }
 
    // 计算当前时间窗口内的请求数
    const now = Date.now();
    const elapsed = now - record.startTime;
 
    // 如果时间窗口已过，重置计数
    if (elapsed > opts.windowMs) {
      record = { count: 1, startTime: now };
    } else {
      // 否则增加计数
      record.count++;
      // 如果超过限制，返回429 Too Many Requests
      if (record.count > opts.max) {
        ctx.status = 429;
        ctx.body = {
          code: 1,
          message: `请求过于频繁，请${Math.ceil((opts.windowMs - elapsed) / 1000)}秒后再试。`,
          retryAfter: Math.ceil((opts.windowMs - elapsed) / 1000),
        };
        return;
      }
    }
 
    // 更新缓存
    cache.set(key, record);
 
    // 设置响应头，告知客户端限流信息
    ctx.set('X-RateLimit-Limit', opts.max);
    ctx.set('X-RateLimit-Remaining', opts.max - record.count);
    ctx.set('X-RateLimit-Reset', Math.ceil((record.startTime + opts.windowMs) / 1000));
 
    // 继续处理请求
    await next();
  };
};